﻿namespace JavaScript8000
{
    using System;
    using System.Text;
    using System.Windows.Forms;

    using JavaScript8000.Common;
    using JavaScript8000.Parser;
    using JavaScript8000.Scaner;

    /// <summary>
    /// Main form of program.
    /// </summary>
    public partial class MainForm : Form
    {
        #region Constants and Fields

        /// <summary>
        /// Results of source code scan.
        /// </summary>
        private ScanResults scanResults;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="MainForm"/> class.
        /// </summary>
        public MainForm()
        {
            this.InitializeComponent();

            this.scanResults = null;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Handles the Click event of the errorListBox control.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// The <see cref="System.EventArgs"/> instance containing the event data.
        /// </param>
        private void ErrorListBoxClick(object sender, EventArgs e)
        {
            this.ScrollToError();
        }

        /// <summary>
        /// Handles the KeyUp event of the errorListBox control.
        /// </summary>
        /// <param name="sender">
        /// The source of the event.
        /// </param>
        /// <param name="e">
        /// The <see cref="System.Windows.Forms.KeyEventArgs"/> instance containing the event data.
        /// </param>
        private void ErrorListBoxKeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                this.ScrollToError();
            }
        }

        /// <summary>
        /// Errors the list box selected index changed.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The <see cref="System.EventArgs"/> instance containing the event data.
        /// </param>
        private void ErrorListBoxSelectedIndexChanged(object sender, EventArgs e)
        {
            this.ScrollToError();
        }

        /// <summary>
        /// Scrolls to error.
        /// </summary>
        private void ScrollToError()
        {
            if (this.errorListBox.Items.Count > 0 && this.scanResults != null && this.errorListBox.SelectedItem != null)
            {
                this.sourceCodeTextBox.SelectionStart = ((ScanError)this.errorListBox.SelectedItem).SymbolIndex;
                this.sourceCodeTextBox.SelectionLength = 1;
                this.sourceCodeTextBox.ScrollToCaret();
                this.sourceCodeTextBox.Focus();
            }
        }

        /// <summary>
        /// Starts the tool strip menu item click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The <see cref="System.EventArgs"/> instance containing the event data.
        /// </param>
        private void StartScanToolStripMenuItemClick(object sender, EventArgs e)
        {
            var scaner = new Scaner.Scaner();
            this.scanResults = scaner.Scan(this.sourceCodeTextBox.Text);
            this.errorListBox.Items.Clear();
            this.errorListBox.Items.AddRange(this.scanResults.Errors.ToArray());

            this.tokenTextBox.Text = this.scanResults.GetStringOfTokensList();

            if (this.scanResults.Errors.Count == 0 && this.scanResults.Tokens.Count > 0)
            {
                // Enable Start Parse button if we have no syntax errors.
                this.startParseToolStripMenuItem.Enabled = true;
            }
        }

        #endregion

        /// <summary>
        /// Handles the TextChanged event of the sourceCodeTextBox control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void sourceCodeTextBox_TextChanged(object sender, EventArgs e)
        {
            this.startParseToolStripMenuItem.Enabled = false;
        }

        /// <summary>
        /// Handles the Click event of the startParseToolStripMenuItem control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void startParseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Show parser window.
            if (this.scanResults != null)
            {
                ParserForm parserForm = new ParserForm(this.scanResults);
                parserForm.Closed += delegate { this.Show();};
                parserForm.Show(this);
                this.Hide();
            }
        }

        private void fUCKToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BrainFuck form = Grammar.GetForm();
            if (!form.Visible)
            {
                form.Show();
            }
        }
    }
}